package com.bluemobi.framework.shiro;

import java.util.HashSet;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;

import com.bluemobi.framework.constant.SystemConstant;
import com.bluemobi.system.model.SysUser;
import com.bluemobi.system.service.SysRoleService;
import com.bluemobi.system.service.SysUserService;
import com.bluemobi.system.vo.RoleVo;

/**
 * 自定义的指定Shiro验证用户登录的类.验证用户登录与权限
 */
@Controller
public class SystemRealm extends AuthorizingRealm {

	protected Log logger = LogFactory.getLog(SystemRealm.class);

	@Resource
	private SysUserService sysUserService;
	@Resource
	private SysRoleService sysRoleService;

	/**
	 * 验证当前登录的Subject
	 *
	 * @param authcToken
	 *            认证令牌
	 * @return AuthenticationInfo
	 * @throws AuthenticationException
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
			throws AuthenticationException {
		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
		String username = token.getUsername();
		if (!StringUtils.isEmpty(username)) {// 判断用户名为空
			SysUser sysUser = null;
			try {
				sysUser = sysUserService.getSysUserByLoginName(username);
			} catch (Exception e) {
				logger.error("登录查询用户信息异常：" + e.getMessage());
			}
			if (null != sysUser) {
				if (sysUser.getState() == 1) {
					return new SimpleAuthenticationInfo(sysUser, sysUser.getPassword(), this.getName());
				} else {
					throw new LockedAccountException();
				}
			}
		}
		throw new UnknownAccountException();
	}

	/**
	 * 验证当前登录的Subject授予角色和权限
	 *
	 * @param principals
	 *            权限集合
	 * @return AuthorizationInfo 认证信息
	 * @throws UnknownAccountException
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		Subject currentUser = SecurityUtils.getSubject();
		if (null != currentUser) {
			Session session = currentUser.getSession();
			if (null != session) {
				SysUser sysUser = (SysUser) session.getAttribute(SystemConstant.SYS_USER_SESSION_KEY);
				if (null != sysUser) {
					SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
					RoleVo roleVo = sysUser.getRoleVo();
					try {
						if (null == roleVo) {
							String uId = sysUser.getSuId();
							roleVo = sysRoleService.getRoleBySuId(uId);
							sysUser.setRoleVo(roleVo);
							session.setAttribute(SystemConstant.SYS_USER_SESSION_KEY, sysUser);
						}
					} catch (Exception e) {
						logger.error("获取用户角色异常：" + e.getMessage());
					}
					if (null != roleVo) {
						Set<String> roleSet = new HashSet<>();
						roleSet.add(roleVo.getRoleCode().trim());
						if (null != roleVo.getPmss()) {
							for (String str : roleVo.getPmss()) {
								info.addStringPermission(str.trim());
							}
						}
						info.setRoles(roleSet);
					}
					return info;
				}
			}
		}
		throw new UnknownAccountException();
	}
}
